package br.ufrn.dimap.MetricDslLanguage.serializer;

import br.ufrn.dimap.MetricDslLanguage.metricDsl.ActivityMetric;
import br.ufrn.dimap.MetricDslLanguage.metricDsl.ArtefactMetric;
import br.ufrn.dimap.MetricDslLanguage.metricDsl.MetricDslPackage;
import br.ufrn.dimap.MetricDslLanguage.metricDsl.Metrics;
import br.ufrn.dimap.MetricDslLanguage.metricDsl.Model;
import br.ufrn.dimap.MetricDslLanguage.metricDsl.TaskMetric;
import br.ufrn.dimap.MetricDslLanguage.services.MetricDslGrammarAccess;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;

@SuppressWarnings("restriction")
public class AbstractMetricDslSemanticSequencer extends AbstractSemanticSequencer {

	@Inject
	protected MetricDslGrammarAccess grammarAccess;
	
	@Inject
	protected ISemanticSequencerDiagnosticProvider diagnosticProvider;
	
	@Inject
	protected ITransientValueService transientValues;
	
	@Inject
	@GenericSequencer
	protected Provider<ISemanticSequencer> genericSequencerProvider;
	
	protected ISemanticSequencer genericSequencer;
	
	
	@Override
	public void init(ISemanticSequencer sequencer, ISemanticSequenceAcceptor sequenceAcceptor, Acceptor errorAcceptor) {
		super.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.genericSequencer = genericSequencerProvider.get();
		this.genericSequencer.init(sequencer, sequenceAcceptor, errorAcceptor);
	}
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == MetricDslPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case MetricDslPackage.ACTIVITY_METRIC:
				if(context == grammarAccess.getActivityMetricRule()) {
					sequence_ActivityMetric(context, (ActivityMetric) semanticObject); 
					return; 
				}
				else break;
			case MetricDslPackage.ARTEFACT_METRIC:
				if(context == grammarAccess.getArtefactMetricRule()) {
					sequence_ArtefactMetric(context, (ArtefactMetric) semanticObject); 
					return; 
				}
				else break;
			case MetricDslPackage.METRICS:
				if(context == grammarAccess.getMetricsRule()) {
					sequence_Metrics(context, (Metrics) semanticObject); 
					return; 
				}
				else break;
			case MetricDslPackage.MODEL:
				if(context == grammarAccess.getModelRule()) {
					sequence_Model(context, (Model) semanticObject); 
					return; 
				}
				else break;
			case MetricDslPackage.TASK_METRIC:
				if(context == grammarAccess.getTaskMetricRule()) {
					sequence_TaskMetric(context, (TaskMetric) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (activityBegin=[Activity|STRING] activityEnd=[Activity|STRING]?)
	 */
	protected void sequence_ActivityMetric(EObject context, ActivityMetric semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=STRING artefacts+=[Artifact|STRING]*)
	 */
	protected void sequence_ArtefactMetric(EObject context, ArtefactMetric semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         name=STRING 
	 *         relatesTo=[Process|ID] 
	 *         description=STRING 
	 *         type=MetricType 
	 *         form=ColectType? 
	 *         id=STRING 
	 *         unit=MetricUnit? 
	 *         (details=ActivityMetric | details=TaskMetric | details=ArtefactMetric)
	 *     )
	 */
	protected void sequence_Metrics(EObject context, Metrics semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     metrics+=Metrics*
	 */
	protected void sequence_Model(EObject context, Model semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     tasks+=[Task|STRING]*
	 */
	protected void sequence_TaskMetric(EObject context, TaskMetric semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
}
